package org.example.utils;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.apache.commons.collections4.CollectionUtils;

import java.util.Objects;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @version: 1.00.00
 * @description: 线程池工厂
 * @copyright: Copyright (c) 2023 立林科技 All Rights Reserved
 * @company: 厦门立林科技有限公司
 * @date: 2023-06-27 8:43
 */
public class ExecutorsFactory {

    /**
     * 创建线程池
     *
     * @param threadNamePrefix
     * @param blockingQueue
     * @param rejectedExecutionHandler
     * @return
     */
    public static ExecutorService newIoInstance(String threadNamePrefix, BlockingQueue<Runnable> blockingQueue, RejectedExecutionHandler rejectedExecutionHandler, boolean isIoIntensive) {
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(threadNamePrefix + "-%d").build();
        if (CollectionUtils.isEmpty(blockingQueue)) {
            blockingQueue = new ArrayBlockingQueue<>(1000);
        }
        if (Objects.isNull(rejectedExecutionHandler)) {
            rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
        }
        int threadNum = Runtime.getRuntime().availableProcessors();
        int coreThreadNum = isIoIntensive ? threadNum * 2 + 1 : threadNum + 1;
        return new ThreadPoolExecutor(coreThreadNum, 2 * coreThreadNum, 300, TimeUnit.MILLISECONDS, blockingQueue, threadFactory, rejectedExecutionHandler);
    }

}
